package org.paic.vertx.httpwrapper.session;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;

public class SessionStore implements SessionOpter {
    private static SessionStore instance = new SessionStore();

    private Timer timer;

    private SessionStore() {
        timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                List<String> clearedKey = new ArrayList<String>();
                for (Iterator<Entry<String, Map<String, String>>> it = store.entrySet().iterator(); it.hasNext();) {
                    Entry<String, Map<String, String>> entry = it.next();
                    String key = entry.getKey();

                    if (isExpired(key)) {
                        clearedKey.add(key);
                    }
                }

                for (String key : clearedKey) {
                    clear(key);
                }
            }

        }, 1000, 1000 * 60);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (timer != null) {
            timer.cancel();
        }
    }

    public static SessionStore getInstance() {
        return instance;
    }

    // default 10 minutes
    private long intervalExpired = 1000 * 60 * 10;

    public void setIntervalExpired(long intervalExpired) {
        this.intervalExpired = intervalExpired;
    }

    private Map<String, Map<String, String>> store = Collections
            .synchronizedMap(new HashMap<String, Map<String, String>>());

    private Map<String, Long> storeExpired = Collections.synchronizedMap(new HashMap<String, Long>());

    public void set(String key, String name, String val) {
        Map<String, String> item = store.get(key);
        if (item == null)
            item = new HashMap<String, String>();

        item.put(name, val);
        store.put(key, item);
    }

    public String get(String key, String name) {
        if (isExpired(key)) {
            clear(key);
            return null;
        }

        Map<String, String> item = store.get(key);
        if (item == null)
            return null;

        return item.get(name);
    }

    public void del(String key, String name) {
        Map<String, String> item = store.get(key);
        if (item == null)
            return;

        item.remove(name);
        store.put(key, item);
    }

    public boolean isExpired(String key) {
        Long lastVisitedMillis = storeExpired.get(key);
        if (lastVisitedMillis == null)
            return false;

        long now = System.currentTimeMillis();
        return now - lastVisitedMillis > intervalExpired;
    }

    public void setVisit(String key) {
        long now = System.currentTimeMillis();
        storeExpired.put(key, now);
    }

    public void clear(String key) {
        store.remove(key);
        storeExpired.remove(key);
    }
}
